import bodyParser from 'body-parser'
import cors from 'cors'
import dayjs from 'dayjs'
import express from 'express'
import mysql from 'mysql'
// @ts-expect-error - node-jsencrypt lacks TypeScript types
import Crypt from 'node-jsencrypt'
import { createHash } from 'crypto'
import { v4 as uuidv4 } from 'uuid'
import * as grpc from '@grpc/grpc-js'
import { AuthService, CheckTokenReq, CheckTokenRes, CheckTokenResData, PrivateKey } from '../common'

const app = express()

app.use(cors()) // 跨域中间件
app.use(bodyParser.json()) // 解析req.body的中间件

const cache = new Map()

// 数据库连接
const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '123456',
  database: 'mmodb'
})

// api路由
app.post('/register', (req, res) => {
  const crypt = new Crypt()
  crypt.setKey(PrivateKey)
  let { account, password } = req.body
  // 非对称加密解密算法处理account和password
  account = crypt.decrypt(account)
  password = crypt.decrypt(password)
  // 使用createHash的sha256算法加密password
  const passwordHash = createHash('sha256').update(password).digest('hex')
  connection.query(
    'INSERT INTO user (account, password, created_time) VALUES (?, ?, ?)',
    [account, passwordHash, dayjs().format('YYYY-MM-DD HH:mm:ss')],
    (err, result) => {
      if (err) {
        console.log(err)
        res.send({ code: 500, message: '注册失败' })
      } else {
        console.log(result)
        res.send({ code: 200, message: '注册成功' })
      }
    }
  )
})

app.post('/login', (req, res) => {
  const crypt = new Crypt()
  crypt.setKey(PrivateKey)
  let { account, password } = req.body
  // 非对称加密解密算法处理account和password
  account = crypt.decrypt(account)
  password = crypt.decrypt(password)
  // 使用createHash的sha256算法加密password
  const passwordHash = createHash('sha256').update(password).digest('hex')
  connection.query('SELECT * FROM user WHERE account = ? AND password = ?', [account, passwordHash], (err, result) => {
    if (err) {
      console.log(err)
      res.send({ code: 500, message: '登录失败' })
      return
    }

    if (result.length > 0) {
      const token = uuidv4()
      cache.set(token, account)
      console.log('cache', cache)
      res.send({ code: 200, message: '登录成功', token })
    }
  })
})

app.get('/', (req, res) => {
  res.send('auth 服务')
})

app.listen(3000, () => {
  console.log('auth 服务启动成功')
})

const server = new grpc.Server()
server.addService(AuthService, {
  checkToken(call: any, callback: Function) {
    const token = call.request.getToken()
    const res = new CheckTokenRes()
    if (cache.has(token)) {
      const data = new CheckTokenResData()
      data.setAccount(cache.get(token))
      res.setData(data)
    } else {
      res.setError('token not exist')
    }
    callback(null, res)
  }
})

server.bindAsync('localhost:3333', grpc.ServerCredentials.createInsecure(), (err, port) => {
  if (err) {
    console.error('Failed to bind:', err)
    return
  }
  server.start()
  console.log('RPC服务启动')
})
